package cn.com.mdx.collection.stack;

import java.util.Iterator;
/*
 * @author huangyuan
 * @description 栈 - 可变数组实现
 */

/**
 * @author huangyuan
 * @description 栈 - 可变数组实现
 */
@SuppressWarnings("unchecked")
public class ResizingArrayStack<Item> implements Iterable<Item> {
    /**
     * 初始化数组默认容量
     */
    private static final int DEFAULT_CAPACITY = 10;
    private int size;
    private Item[] items;

    public ResizingArrayStack() {
        size = 0;
        items = (Item[]) new Object[DEFAULT_CAPACITY];
    }

    /**
     * @param item 入栈
     * @methodName push
     * @Desc 元素入栈
     * @Author huangyuan
     */
    public void push(Item item) {
        //如果容量和数组长度相同，扩大数组容量为原来2倍
        if (size + 1 == items.length) resize(items.length * 2);
        items[size++] = item;
    }

    /**
     * @return Item 出栈元素
     * @methodName pop
     * @Desc 元素出栈
     * @Author huangyuan
     */
    public Item pop() {
        if (isEmpty()) throw new UnsupportedOperationException("栈为空无法进行此操作");
        Item item = items[size - 1];
        items[--size] = null;
        //缩小数组长度为原来的1/2
        if (size > 0 && size == items.length / 4) resize(items.length / 2);
        return item;
}

    /**
     * @return 栈容量
     * @methodName size
     * @Desc 获取栈容量
     * @Author huangyuan
     */
    public int size() {
        return size;
    }

    /**
     * @return false 栈不为空 true 栈为空
     * @methodName isEmpty
     * @Desc 栈是否为空
     * @Author huangyuan
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * @return Iterator 可迭代对象
     * @methodName iterator
     * @Desc
     * @Author huangyuan
     * @Date 2020/7/8 5:45 下午
     */
    @Override
    public Iterator<Item> iterator() {
        return new ResizingArrayStackIterator();
    }

    private class ResizingArrayStackIterator implements Iterator<Item> {
        int index = size;

        @Override
        public boolean hasNext() {
            return index > 0;
        }

        @Override
        public Item next() {
            return items[--index];
        }
    }

    /**
     * @param arrayLength 重置后的数组长度
     * @return void
     * @Author huangy
     * @description //TODO 重置数组长度
     * @date 6:06 下午 2020/8/5
     **/
    private void resize(int arrayLength) {
        assert size > items.length;
        Item[] newItems = (Item[]) new Object[arrayLength];
        //数组拷贝
        System.arraycopy(items, 0, newItems, 0, size);
        items = newItems;
    }

    public static void main(String[] args) {
        ResizingArrayStack<String> resizingArrayStack = new ResizingArrayStack<>();
        for (int i = 0; i < 100; i++) {
            resizingArrayStack.push("0" + i);
        }
        System.out.println(resizingArrayStack.pop());
        System.out.println(resizingArrayStack.pop());
        System.out.println(resizingArrayStack.pop());
        System.out.println("--------------------------");
        resizingArrayStack.push("0" + 1000);
        resizingArrayStack.push("0" + 1001);
        for (String s : resizingArrayStack) {
            System.out.println(s);
        }
        System.out.println("--------------------------");
        System.out.println(resizingArrayStack.pop());
        System.out.println(resizingArrayStack.pop());
        System.out.println(resizingArrayStack.pop());
    }

}
